﻿#include<windows.h>
#include "windowClass/ZdsjWindow.h"
#include "dxClass/GraphicsWithDx9.h"
#include "Timer/Timer.h"
// #include <WinSock2.h>  
#include <Iphlpapi.h>
#include "Source/Internet.h"
#include "Source/Cpu.h"

#pragma comment(lib,"Iphlpapi.lib") //需要添加Iphlpapi.lib库 

class App{
public:
    App(HWND parent, HINSTANCE hinstance)
    {
        this->_window = new ZdsjWindow(parent, hinstance);
        this->_graphics = new GraphicsWithDx9(this->_window->getHwnd());
        this->_timer = new Timer();
        this->_internet = new Internet();
        this->_cpu = new Cpu();
        this->_cpu->setInvokeFrame(this->_frame);
    }
    ~App()
    {
        this->_alive = false;
        if(this->_thread != nullptr)
        {
            this->_thread->join();
        }
        delete this->_thread;
        delete this->_window;
        delete this->_graphics;
        delete this->_timer;
        delete this->_internet;
        delete this->_cpu;
    }
    int run()
    {
        this->_thread = new std::thread(&App::doFrame, this);
        return this->messageLoop();
    }
private:
    int messageLoop()
    {
        MSG msg;
        BOOL ret;
        // PeekMessage不停调用导致CPU占用率高  一行代码高了	10%
        while ((ret = GetMessageW(&msg, nullptr, 0, 0)) != 0) {
            if (ret == -1) {
                // handle the error and possibly exit
                return MESSAGE_HANDLE_ERROR_RETURN;
            }
            else {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
        if (ret == -1) {
            return UNKOWN_ERROR_RETURN;
        }
        else {
            this->_alive = false;
            return static_cast<int>(msg.wParam);
        }
    }
    void doFrame() const
    {
        std::chrono::duration<double> time = std::chrono::duration<double>::zero();
        this->_timer->setFps(this->_frame);
        while(this->_alive)
        {

            // doSomething
            if(this->_internet->doFrame())
            {
                this->_graphics->putSlot(this->_internet->getInSpeed(), 0);
                this->_graphics->putSlot(this->_internet->getOutSpeed(), 1);
            }
            if(this->_cpu->doFrame())
            {
                this->_graphics->putSlot(this->_cpu->getCpuRate(), 2);
                this->_graphics->putSlot(this->_cpu->getMemory(), 3);
            }
            this->_graphics->doFrame();
            // this->wnd->exchange();
            time = this->_timer->nextFps();
        }
    }

    ZdsjWindow* _window = nullptr;
    GraphicsWithDx9* _graphics = nullptr;
    Timer* _timer = nullptr;
    std::thread* _thread = nullptr;
    bool _alive = true;    
    const int _frame = 60;
    Internet* _internet = nullptr;
    Cpu* _cpu = nullptr;
};

INT WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ INT nCmdShow)
{
    // taskbar win11下设置窗口为其子窗口
    HWND parent = FindWindowW(L"Shell_TrayWnd", NULL);
    // taskbar下的子窗口, 貌似win10设置其为子窗口
    // HWND hwnd = FindWindowExW(parent, NULL, L"ReBarWindow32", NULL);
    // HWND hwnd = FindWindowExW(hwnd, NULL, L"MSTaskSwWClass", NULL); 最小化不太明白
    App* app = new App(parent, hInstance);
    int ret = app->run();
    delete app;
    return 0;
}
